package com.apes.fn.server.transferVehicle.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.crm.customerExpand.FnCustomerExpand;
import com.apes.fn.scm.retailOrder.service.RetailOrderExtensionService;
import com.apes.fn.server.pickUpCar.model.PickUpCar;
import com.apes.fn.server.pickUpCar.repository.PickUpCarRepository;
import com.apes.fn.server.servicePlan.service.AbstractPlan;
import com.apes.fn.server.servicePlan.service.ServicePlanceService;
import com.apes.fn.server.transferVehicle.model.InnerPickDeliveryUpCar;
import com.apes.fn.server.transferVehicle.model.InnerPickDeliveryUpCarItem;
import com.apes.fn.server.transferVehicle.repository.InnerPickDeliveryUpCarRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.express.FuncAlias;
import com.apes.framework.util.DistributedLock;
import com.apes.framework.util.MapUtil;
import com.apes.hr.base.repository.EmployeeRepository;
import com.apes.hr.transfer.repository.TransferApplicationItemRepository;
import com.apes.pi.service.PiManager;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.frame.model.Branch;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.model.Store;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.frame.repository.StoreRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apestech.framework.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 内协交接车单服务类
 * Creator: linwz
 * CreateDate: 2020-04-27 15:35
 * Description:
 **/
@Service("innerPickDeliveryUpCarService")
public class InnerPickDeliveryUpCarService extends DomainService {
    @Autowired
    private InnerPickDeliveryUpCarRepository innerPickDeliveryUpCarRepository;

    @Autowired
    private PickUpCarRepository pickUpCarRepository;

    @Autowired
    private DeptRepository deptRepository;

    @Autowired
    private StoreRepository storeRepository;
    @Autowired
    private PartyRoleRepository partyRoleRepository;
    @Autowired
    private EmployeeRepository employeeRepository;
    @Autowired
    private SequenceService sequenceService;
    @Autowired
    private PiManager piManager;
    @Autowired
    private EnumerationRepository enumerationRepository;
    @Autowired
    private TransferApplicationItemRepository transferApplicationItemRepository;
    @Autowired
    private DistributedLock distributedLock;
    @Value("${apes.switched:false}")
    private Boolean switched;

    /**
     * 通过车牌，寻找有效门店内协接车单，有效的只能有一张
     *
     * @param req
     * @return
     */
    public InnerPickDeliveryUpCar findValidateByCphmMd(SimpleRequest req) {
        JSONObject jo = req.getJO();
        Dept dept;
        String carLicense;
        try {
            dept = MapUtil.getO(jo.getJSONObject("dept"), Dept.class);
        } catch (Exception e) {
            throw new RuntimeException("寻找有效外协信息失败");
        }

        try {
            carLicense = jo.getJSONObject("customerCar").getString("carLicense");
        } catch (Exception e) {
            throw new RuntimeException("mistake:innerError——查找当前车辆外协信息有误");
        }

        return getInnerPickDeliveryUpCar(dept, carLicense);
    }

    public InnerPickDeliveryUpCar getInnerPickDeliveryUpCar(Dept dept, String carLicense) {
        List<InnerPickDeliveryUpCar> innerPickUpCars = innerPickDeliveryUpCarRepository.findAll(
                JpaDsl.toCriteriaByEq("fnCustomerExpand.carLicense", carLicense, "otherSideDept.id", dept.getId(), "state", "get"));
        if (innerPickUpCars == null || innerPickUpCars.size() == 0) return null;
        return innerPickUpCars.stream().findFirst().get();
    }

    /**
     * 创建内协交接车单
     *
     * @param request
     * @return
     */
    public InnerPickDeliveryUpCar create(SimpleRequest request) {
        InnerPickDeliveryUpCar innerPickDeliveryUpCar = updateOrInsertCustomerExpand(request);
        SpringManager.getBean(AbstractPlan.class).copyFnCustomerExpandToOrderSide(innerPickDeliveryUpCar.getFnCustomerExpand(),innerPickDeliveryUpCar.getOtherSideDept());
        // 校验车辆是否有接车单  pickA
        Dept belongDept = innerPickDeliveryUpCar.getBelongDept();
        String licenseNumber = innerPickDeliveryUpCar.getLicenseNumber();
        Enumeration enumeration = enumerationRepository.findByTypeAndValue("pickA", "pickCarType");
        List<PickUpCar> pickUpCarList = pickUpCarRepository.findByLicenseNumberAndPickCarTypeAndState(licenseNumber, enumeration, "approve");
        pickUpCarList = pickUpCarList.stream().filter(pickUpCar -> pickUpCar.getDept() == belongDept).collect(Collectors.toList());
        if (pickUpCarList.isEmpty()) throw new RuntimeException("请在接车后发起内协。");

        innerPickDeliveryUpCar.setPickUpCar(pickUpCarList.stream().findFirst().get());
        innerPickDeliveryUpCar.setState("create");
        innerPickDeliveryUpCar.setBeginDate(new Date());
        Dept otherSideDept = innerPickDeliveryUpCar.getOtherSideDept();
        Store belongStore = storeRepository.findByDept(belongDept);
        Store store = storeRepository.findByDept(otherSideDept);
        if (belongStore == null) throw new RuntimeException("发起部门找不到对应门店信息。");
        if (store == null) throw new RuntimeException("接收部门找不到对应门店信息。");

        //  明细数据处理
        InnerPickDeliveryUpCarItem item = innerPickDeliveryUpCar.getInnerPickDeliveryUpCarItemList().stream().findFirst().get();
        item.setNodeDescription("create");
        item.setOperateDate(new Date());
        if (Optional.of(belongStore.getStoreType().getDescription()).orElseThrow(() -> new RuntimeException("发起部门门店类型为空。")).equals("钣喷基地")
                && Optional.of(store.getStoreType().getDescription()).orElseThrow(() -> new RuntimeException("接收部门门店类型为空。")).equals("钣喷基地")) {
            item.setDispatcherDept(belongDept);
        } else if (!Optional.of(belongStore.getStoreType().getDescription()).orElseThrow(() -> new RuntimeException("发起部门门店类型为空。")).equals("钣喷基地")
                && !Optional.of(store.getStoreType().getDescription()).orElseThrow(() -> new RuntimeException("接收部门门店类型为空。")).equals("钣喷基地")) {
            item.setDispatcherDept(belongDept);
        } else {
            item.setDispatcherDept(otherSideDept);
        }
        return innerPickDeliveryUpCarRepository.saveAndFlush(innerPickDeliveryUpCar);
    }

    /**
     * fnInnerPickDeliveryUpCar.query
     * @param request
     * @return customAction="true"
     * @throws Exception
     */
    public com.apestech.framework.json.JSONObject fnInnerPickDeliveryUpCarQuery(SimpleRequest request) throws Exception {
        JSONObject jo = request.getJO();
        JSONArray condition = jo.getJSONArray("condition");
        if (condition != null) {
            for (int i = 0; i < condition.size(); i++) {
                if ("J_OPERATE_DATE".equals(condition.getJSONObject(i).getString("field"))){
                    JSONObject json = new JSONObject();
                    if("GTE".equals(condition.getJSONObject(i).getString("operator"))){
                        json.put("field","O_BEGIN_DATE");
                        json.put("operator","EQ");
                        json.put("value",condition.getJSONObject(i).getString("value"));
                        json.put("type","date");
                        condition.add(json);
                    }else if("LTE".equals(condition.getJSONObject(i).getString("operator"))){
                        json.put("field","O_BEGIN_END_DATE");
                        json.put("operator","EQ");
                        json.put("value",condition.getJSONObject(i).getString("value"));
                        json.put("type","date");
                        condition.add(json);
                    }
                }
                if ("G_OPERATE_DATE".equals(condition.getJSONObject(i).getString("field"))){
                    JSONObject json = new JSONObject();
                    if("GTE".equals(condition.getJSONObject(i).getString("operator"))){
                        json.put("field","O_OTHER_SIDE_DATE");
                        json.put("operator","EQ");
                        json.put("value",condition.getJSONObject(i).getString("value"));
                        json.put("type","date");
                        condition.add(json);
                    }else if("LTE".equals(condition.getJSONObject(i).getString("operator"))){
                        json.put("field","O_OTHER_SIDE_END_DATE");
                        json.put("operator","EQ");
                        json.put("value",condition.getJSONObject(i).getString("value"));
                        json.put("type","date");
                        condition.add(json);
                    }
                }
                if ("SC_OPERATE_DATE".equals(condition.getJSONObject(i).getString("field"))){
                    JSONObject json = new JSONObject();
                    if("GTE".equals(condition.getJSONObject(i).getString("operator"))){
                        json.put("field","SC_OPERATE_DATE");
                        json.put("operator","EQ");
                        json.put("value",condition.getJSONObject(i).getString("value"));
                        json.put("type","date");
                        condition.add(json);
                    }else if("LTE".equals(condition.getJSONObject(i).getString("operator"))){
                        json.put("field","SC_OPERATE_END_DATE");
                        json.put("operator","EQ");
                        json.put("value",condition.getJSONObject(i).getString("value"));
                        json.put("type","date");
                        condition.add(json);
                    }
                }
            }
            jo.put("condition", condition);
        }
        return com.apestech.framework.json.JSON.toJSON(jo.toJSONString());
    }


    /**
     * 更新内协交接车单
     * 调度信息
     *  APP 传入 对应的人员是否需要计算提成
     *
     * @param simpleRequest
     * @return
     */
    public InnerPickDeliveryUpCar updateDispatcher(SimpleRequest simpleRequest) {
        JSONObject json = simpleRequest.getJO();
        String id = json.getString("innerPickDeliveryUpCarId");
        String state = json.getString("state");

        // 将传入的值，转为 InnerPickDeliveryUpCarItem
        InnerPickDeliveryUpCarItem item = simpleRequest.getO(InnerPickDeliveryUpCarItem.class);

        InnerPickDeliveryUpCar innerPickDeliveryUpCar = innerPickDeliveryUpCarRepository.findOne(id);
        innerPickDeliveryUpCar.getInnerPickDeliveryUpCarItemList().stream()
                .filter(innerPickDeliveryUpCarItem -> innerPickDeliveryUpCarItem.getNodeDescription().equals(state))
                .forEach(innerPickDeliveryUpCarItem -> {

                    innerPickDeliveryUpCarItem.setDispatcherDate(new Date());
                    innerPickDeliveryUpCarItem.setChauffeur(item.getChauffeur());
                    innerPickDeliveryUpCarItem.setDispatcherDept(item.getDispatcherDept());
                    innerPickDeliveryUpCarItem.setDispatcherUid(item.getDispatcherUid());

                    // commissionFlag 计算提成标记
                    innerPickDeliveryUpCarItem.setCommissionFlag(item.isCommissionFlag());
                });
        innerPickDeliveryUpCar = innerPickDeliveryUpCarRepository.saveAndFlush(innerPickDeliveryUpCar);
        return innerPickDeliveryUpCar;
    }

    /**
     * 内协交接车单 接车
     *
     * @param simpleRequest
     * @return
     */
    public InnerPickDeliveryUpCar getDeliveryUpCar(SimpleRequest simpleRequest) {
        Map map = simpleRequest.getMap();
        JSONObject chauffeur = (JSONObject) map.get("chauffeur");
        if (!map.containsKey("chauffeur") || chauffeur == null || chauffeur.get("id").equals("")) {
            throw new RuntimeException("请先确认调度司机");
        }
        String id = (String) map.get("innerPickDeliveryUpCarId");
        String operateDept = (String) map.get("operateDept");
        InnerPickDeliveryUpCar innerPickDeliveryUpCar = innerPickDeliveryUpCarRepository.findOne(id);
        if (!innerPickDeliveryUpCar.getOtherSideDept().getId().equals(operateDept)) {
            throw new RuntimeException("此状态仅限接收门店操作。");
        }
        InnerPickDeliveryUpCarItem innerPickDeliveryUpCarItem = simpleRequest.getO(InnerPickDeliveryUpCarItem.class);
        InnerPickDeliveryUpCarItem create = innerPickDeliveryUpCar.getInnerPickDeliveryUpCarItemList().stream().filter(item -> item.getNodeDescription().equals("create")).findFirst().orElse(null);
        if (create!=null) innerPickDeliveryUpCarItem.setCommissionFlag(create.isCommissionFlag());
        innerPickDeliveryUpCarItem.setOperateDate(new Date());
        innerPickDeliveryUpCarItem.setNodeDescription("get");

        String code = sequenceService.getId("fn_inner_pick_del_up_car_item");//获取序列;
        innerPickDeliveryUpCarItem.setId(code);
        innerPickDeliveryUpCarItem.setInnerPickDeliveryUpCar(innerPickDeliveryUpCar);

        List<InnerPickDeliveryUpCarItem> innerPickDeliveryUpCarItemList = innerPickDeliveryUpCar.getInnerPickDeliveryUpCarItemList();
        innerPickDeliveryUpCarItemList.add(innerPickDeliveryUpCarItem);

        innerPickDeliveryUpCar.setState("get");
        innerPickDeliveryUpCar.setExpOtherSideDate(innerPickDeliveryUpCarItem.getOtherSideDate());
        if (innerPickDeliveryUpCar.getJJCDH() == null && !switched) {
            String jjcdh = synJJCD(innerPickDeliveryUpCar, innerPickDeliveryUpCarItem);
            innerPickDeliveryUpCar.setJJCDH(jjcdh);
        }
        innerPickDeliveryUpCar = innerPickDeliveryUpCarRepository.saveAndFlush(innerPickDeliveryUpCar);
        return innerPickDeliveryUpCar;
    }

    /**
     * 更新内协交接车单 归还
     *
     * @param simpleRequest
     * @return
     */
    public InnerPickDeliveryUpCar returnDeliveryUpCar(SimpleRequest simpleRequest) {
        Map map = simpleRequest.getMap();
        JSONObject chauffeur = (JSONObject) map.get("chauffeur");
        if (!map.containsKey("chauffeur") || chauffeur == null || chauffeur.get("id").equals("")) {
            throw new RuntimeException("请先确认调度司机");
        }
        String id = (String) map.get("innerPickDeliveryUpCarId");
        String operateDept = (String) map.get("operateDept");
        InnerPickDeliveryUpCar innerPickDeliveryUpCar = innerPickDeliveryUpCarRepository.findOne(id);
        if (!innerPickDeliveryUpCar.getOtherSideDept().getId().equals(operateDept)) {
            throw new RuntimeException("此状态仅限接收门店操作。");
        }

        // 主表状态
        innerPickDeliveryUpCar.setState("return");
        innerPickDeliveryUpCar.setOtherSideDate(new Date());

        // 明细表处理
        InnerPickDeliveryUpCarItem innerPickDeliveryUpCarItem = simpleRequest.getO(InnerPickDeliveryUpCarItem.class);
        String code = sequenceService.getId("fn_inner_pick_del_up_car_item");//获取序列;
        innerPickDeliveryUpCarItem.setId(code);

        innerPickDeliveryUpCarItem.setOperateDate(new Date());
        innerPickDeliveryUpCarItem.setNodeDescription("return");
        innerPickDeliveryUpCarItem.setInnerPickDeliveryUpCar(innerPickDeliveryUpCar);
        innerPickDeliveryUpCarItem.setBelongDept(innerPickDeliveryUpCar.getOtherSideDept());
        innerPickDeliveryUpCarItem.setOtherSideDept(innerPickDeliveryUpCar.getBelongDept());

        List<InnerPickDeliveryUpCarItem> innerPickDeliveryUpCarItemList = innerPickDeliveryUpCar.getInnerPickDeliveryUpCarItemList();
        InnerPickDeliveryUpCarItem item = innerPickDeliveryUpCarItemList.stream().filter(item1 -> item1.getNodeDescription().equals("create")).findFirst().get();
        innerPickDeliveryUpCarItem.setDispatcherDept(item.getDispatcherDept());
        innerPickDeliveryUpCarItemList.add(innerPickDeliveryUpCarItem);

        // 如果接车时，赋能库存同步范围表里 存在就不生成旧框架接车单，所以交接车单号为空
        if (innerPickDeliveryUpCar.getJJCDH() != null && !switched) {
            synGHJJCD(innerPickDeliveryUpCar, innerPickDeliveryUpCarItem);
        }
        innerPickDeliveryUpCar = innerPickDeliveryUpCarRepository.saveAndFlush(innerPickDeliveryUpCar);

        return innerPickDeliveryUpCar;
    }

    /**
     * 更新内协交接车单 确认收车
     *
     * @param simpleRequest
     * @return
     */
    public InnerPickDeliveryUpCar confirmReturn(SimpleRequest simpleRequest) {
        Map map = simpleRequest.getMap();
        String id = (String) map.get("innerPickDeliveryUpCarId");
        String operateDept = (String) map.get("operateDept");
        InnerPickDeliveryUpCar innerPickDeliveryUpCar = innerPickDeliveryUpCarRepository.findOne(id);
        if (!innerPickDeliveryUpCar.getBelongDept().getId().equals(operateDept)) {
            throw new RuntimeException("此状态仅限发起门店操作。");
        }
        InnerPickDeliveryUpCarItem innerPickDeliveryUpCarItem = simpleRequest.getO(InnerPickDeliveryUpCarItem.class);
        innerPickDeliveryUpCarItem.setOperateDate(new Date());
        innerPickDeliveryUpCarItem.setNodeDescription("confirm");
        String code = sequenceService.getId("fn_inner_pick_del_up_car_item");//获取序列;
        innerPickDeliveryUpCarItem.setId(code);
        innerPickDeliveryUpCarItem.setInnerPickDeliveryUpCar(innerPickDeliveryUpCar);

        List<InnerPickDeliveryUpCarItem> innerPickDeliveryUpCarItemList = innerPickDeliveryUpCar.getInnerPickDeliveryUpCarItemList();
        innerPickDeliveryUpCarItemList.add(innerPickDeliveryUpCarItem);
        innerPickDeliveryUpCar.setState("confirm");
        return innerPickDeliveryUpCarRepository.saveAndFlush(innerPickDeliveryUpCar);
    }

    /**
     * 更新内协交接车单 终止
     *
     * @param simpleRequest
     * @return
     */
    public InnerPickDeliveryUpCar repeal(SimpleRequest simpleRequest) {
        Map map = simpleRequest.getMap();
        String id = (String) map.get("innerPickDeliveryUpCarId");
        String repealCause = (String) map.get("repealCause");

        InnerPickDeliveryUpCar innerPickDeliveryUpCar = innerPickDeliveryUpCarRepository.findOne(id);
        innerPickDeliveryUpCar.setState("repeal");
        innerPickDeliveryUpCar.setRepealCause(repealCause);
        innerPickDeliveryUpCar.setRepealDate(new Date());
        return innerPickDeliveryUpCarRepository.saveAndFlush(innerPickDeliveryUpCar);
    }


    /***
     * 保存会员和车辆数据
     */
    private InnerPickDeliveryUpCar updateOrInsertCustomerExpand(SimpleRequest request) {
        JSONObject tempJson = request.getJO();

        InnerPickDeliveryUpCar innerPickDeliveryUpCar = request.getO(InnerPickDeliveryUpCar.class);
        List<PickUpCar> list = pickUpCarRepository.findByLicenseNumberAndDeptAndState(innerPickDeliveryUpCar.getLicenseNumber(), innerPickDeliveryUpCar.getOtherSideDept(), "approve");
        if (list.size() > 0)
            throw new RuntimeException(innerPickDeliveryUpCar.getOtherSideDept().getName() + "已存在" + innerPickDeliveryUpCar.getLicenseNumber() + "的接车单，请通知对方关闭接车单后再做单!!!");
        insetFnCustomerExpand(tempJson, innerPickDeliveryUpCar);
        return innerPickDeliveryUpCar;
    }

    private void insetFnCustomerExpand(JSONObject tempJson, InnerPickDeliveryUpCar innerPickDeliveryUpCar) {
        Dept dept = innerPickDeliveryUpCar.getBelongDept();
        FnCustomerExpand customerExpand = SpringManager.getBean(ServicePlanceService.class)
                .findValidServiceFnCustomerExpand(innerPickDeliveryUpCar.getBelongDept(), innerPickDeliveryUpCar.getLicenseNumber());
        if (customerExpand != null) {
            innerPickDeliveryUpCar.setFnCustomerExpand(customerExpand);
        } else {
            customerExpand = this.invoke("fn.customerExpand.updateOrInsert", MapUtil.mapper(
                    "customerExpand", tempJson.get("customerExpand"),
                    "customer", tempJson.get("customerInfo"),
                    "customerCar", tempJson.get("customerCar")
            ));
            innerPickDeliveryUpCar.setFnCustomerExpand(customerExpand);
        }

    }

    private void checkData(SimpleRequest request) {
        String id = request.get("id");
        InnerPickDeliveryUpCar innerPickDeliveryUpCar = innerPickDeliveryUpCarRepository.findOne(id);
        if (innerPickDeliveryUpCar == null) throw new RuntimeException("内协交接车单【" + id + "】在系统中不存在。");
    }

    /**
     * 查询内协常用门店
     *
     * @param request
     * @return
     */
    public List queryDept(SimpleRequest request) {
        String deptId = request.get("deptId");
        List<Map> deptList = new ArrayList<>();
        List<String> deptIdList = innerPickDeliveryUpCarRepository.findByBelongDeptAndDesc(deptId);
        deptIdList.forEach(id -> {
            Dept dept = deptRepository.findOne(id);
            Store store = storeRepository.findByDept(dept);
            if (store != null) {
                Map map = MapUtil.mapper(
                        "id", dept.getId(),
                        "name", dept.getName(),
                        "address", store.getAddress());
                deptList.add(map);
            }
        });
        return deptList;
    }

    /**
     * 查询调度方 门店人员
     *
     * @param request
     * @return
     */
    public List queryPartyRole(SimpleRequest request) {
        String deptId = request.get("deptId");
        Branch branch = deptRepository.findOne(deptId).getBranch();
        List<Map> mapList = new ArrayList<>();

        employeeRepository.findByWorkBranch(branch).stream()
                .forEach(employee -> {
                    PartyRole partyRole = partyRoleRepository.findByPartyIdAndRoleId(employee.getParty().getId(), "Employee");
                    Map map = MapUtil.mapped(partyRole);
                    map.put("workPost", employee.getPost());
                    mapList.add(map);
                });
        transferApplicationItemRepository.findToSup(branch, new Date()).stream()
                .forEach(transferApplicationItem -> {
                    PartyRole partyRole = partyRoleRepository.findByPartyIdAndRoleId(transferApplicationItem.getTransferUid().getParty().getId(), "Employee");
                    Map map = MapUtil.mapped(partyRole);
                    map.put("workPost", transferApplicationItem.getTransferUid().getPost());
                    mapList.add(map);
                });
        return mapList;
    }

    /**
     * App 模糊查询人员
     *
     * @param request
     * @return
     */
    public List findPartyRole(SimpleRequest request) {
        JSONObject jsonObject = request.getJO();
        String id = jsonObject.getString("key");
        String deptId = jsonObject.getString("deptId");
        Branch branch = deptRepository.findOne(deptId).getBranch();
        List<PartyRole> partyRoleList = new ArrayList<>();
        List<Map> mapList = new ArrayList<>();
        employeeRepository.findByLikeName(id).stream()
                .filter(employee -> employee.isDriver() && employee.getWorkBranch().equals(branch))
                .forEach(employee -> {
                    PartyRole partyRole = partyRoleRepository.findByPartyIdAndRoleId(employee.getParty().getId(), "Employee");
                    Map map = MapUtil.mapped(partyRole);
                    map.put("workPost", employee.getPost());
                    mapList.add(map);
                });
//        List<Party> partyList = employeeRepository.findByLikeName(id).stream()
//                .filter(employee -> employee.isDriver() && employee.getWorkBranch().equals(branch))
//                .map(Employee::getParty).collect(Collectors.toList());
//        for (int i = 0; i < partyList.size(); i++) {
//            Party party = partyList.get(i);
//            PartyRole partyRole = partyRoleRepository.findByPartyIdAndRoleId(party.getId(), "Employee");
//            partyRoleList.add(partyRole);
//        }

        return mapList;
    }

    /***
     * 功能： 根据车牌查找接车单
     * @param request
     * @return
     * @throws RuntimeException
     */
    public InnerPickDeliveryUpCar findOneWithID(SimpleRequest request) throws Exception {
        String licenseNumber = request.get("licenseNumber");
        List<InnerPickDeliveryUpCar> list = innerPickDeliveryUpCarRepository.findAll(
                JpaDsl.toCriteriaByEq("licenseNumber", licenseNumber)
        );
        return list.get(0);
    }


    /***
     * 功能： 根据车牌查找有效接车单
     * @param request
     * @return
     * @throws RuntimeException
     */
    public List findByLicenseNumber(SimpleRequest request) throws Exception {
        String licenseNumber = request.get("licenseNumber");
        List<InnerPickDeliveryUpCar> list = innerPickDeliveryUpCarRepository.findAll(
                JpaDsl.toCriteriaByEq("licenseNumber", licenseNumber)
        );
        list = list.stream().filter(innerPickDeliveryUpCar -> innerPickDeliveryUpCar.getState().equals("get")
                || innerPickDeliveryUpCar.getState().equals("return") || innerPickDeliveryUpCar.getState().equals("create")
        ).collect(Collectors.toList());
        return innerPickDeliveryUpCarListToMapList(list);
    }

    public Map findStoreAddress(Dept dept) {
        Store store = storeRepository.findByDept(dept);
        if (store == null) {
            throw new RuntimeException(dept.getName() + "找不到对应的门店。");
        }
        Map map = MapUtil.mapper(
                "id", dept.getId(),
                "name", dept.getName(),
                "address", store.getAddress());
        return map;
    }

    /**
     * 基地接车时同步到旧系统
     *
     * @param innerPickDeliveryUpCar
     */
    public String synJJCD(InnerPickDeliveryUpCar innerPickDeliveryUpCar, InnerPickDeliveryUpCarItem item) {
        Store belongStore = storeRepository.findByDept(innerPickDeliveryUpCar.getBelongDept());
        Store store = storeRepository.findByDept(innerPickDeliveryUpCar.getOtherSideDept());
        if (belongStore == null) throw new RuntimeException("发起部门找不到对应门店信息。");
        if (store == null) throw new RuntimeException("接收部门找不到对应门店信息。");
        JSONObject JJCD = new JSONObject();
        JJCD.put("JJCDH", null);
        JJCD.put("GSID", "1001");
        JJCD.put("DJLXID", "JC0");
        JJCD.put("DJLXMC", "接车单");
//        JJCD.put("LYDJLX", "NXJC0");
//        JJCD.put("LYDJMC", "内协交接车");
//        JJCD.put("LYDJHM", innerPickDeliveryUpCar.getId());
        JJCD.put("JJLX", 1);
        //先进行车辆等数据同步
        JSONObject reJson =
                this.invoke("fn.deliveryOrder.acrossSystemCreateVipDetail", MapUtil.mapper(
                        "customerExpandId", innerPickDeliveryUpCar.getFnCustomerExpand().getId(),
                        "deliveryCompanyId", innerPickDeliveryUpCar.getBelongDept().getCompany().getId(),
                        "receiptCompanyId", innerPickDeliveryUpCar.getOtherSideDept().getCompany().getId()
                ));

        String sVIPID;
        String sCLNM;

        try {
            sVIPID = JSONObject.parseObject(reJson.getString("obj")).getString("VIPID");
            sCLNM = JSONObject.parseObject(reJson.getString("obj")).getString("CLNM");
        } catch (Exception e) {
            throw new RuntimeException("转内协失败，同步车辆信息有误");
        }
        JJCD.put("VIPID", sVIPID);
        JJCD.put("CLNM", sCLNM);
        JJCD.put("CPHM", innerPickDeliveryUpCar.getLicenseNumber());

        switch (item.getFuelMeter().getDescription()) {
            case "空":
                JJCD.put("YBWDS", "E");
                break;
            case "1/4":
                JJCD.put("YBWDS", "1/4");
                break;
            case "2/4":
                JJCD.put("YBWDS", "1/2");
                break;
            case "3/4":
                JJCD.put("YBWDS", "3/4");
                break;
            case "满":
                JJCD.put("YBWDS", "F");
                break;

        }
        JJCD.put("MDGSID", innerPickDeliveryUpCar.getOtherSideDept().getCompany().getId());
        JJCD.put("MDID", store.getCode());
        JJCD.put("MDMC", store.getName());
        JJCD.put("GHYBWDS", null);
        JJCD.put("GHLCBDS", null);
//        JJCD.put("GHMDID", innerPickDeliveryUpCar.getOtherSideDept().getId());
//        JJCD.put("GHMDMC", innerPickDeliveryUpCar.getOtherSideDept().getName());
        JJCD.put("ZDR", "yyadmin");
//        JJCD.put("ZDRQ_SJ", innerPickDeliveryUpCar.getCreateDate());
        JJCD.put("JIECR", item.getOperateUid().getId());
//        JJCD.put("JCRQ_SJ",item.getOperateDate());
        JJCD.put("JIAOCR", item.getChauffeur().getName());
        JJCD.put("TS01", innerPickDeliveryUpCar.getLastUpdatedStamp());
//        JJCD.put("YJJCRQ_SJ", item.getOperateDate()==null?new Date():item.getOperateDate());
        JJCD.put("DJZT", 20);
//        JJCD.put("SCR", "1001");
//        JJCD.put("SCRQ_SJ", "广州市集群车宝汽车服务连锁有限公司");
        JJCD.put("JCMDID", belongStore.getCode());
        JJCD.put("JCMDMC", belongStore.getName());

        JJCD.put("NXMDID", belongStore.getCode());
        JJCD.put("CZY", item.getOperateUid().getName());
        JJCD.put("LCBDS", item.getMileage());
        JJCD.put("YSPHM", 0);
        JJCD.put("JCSJID", item.getChauffeur().getId());
        JJCD.put("JCSJMC", item.getChauffeur().getName());
        JSONObject category = piManager.synErp("jjcdService.insertAppNXJJCD", JJCD);
        String returnData = category.get("obj").toString();
        return returnData;
    }


    /***
     * 功能： 门店待办 ，
     * @param request
     * @return
     * @throws RuntimeException
     */
    public Map findByDept(SimpleRequest request) throws Exception {
        String deptId = request.get("DeptId");
        // 待内协还车
        List<InnerPickDeliveryUpCar> getStatelist = innerPickDeliveryUpCarRepository.findAll(
                JpaDsl.toCriteriaByEq("otherSideDept.id", deptId, "state", "get")
        );
        getStatelist.sort(Comparator.comparing(InnerPickDeliveryUpCar::getCreateDate).reversed());
        // 待内协调度
        List<InnerPickDeliveryUpCar> otherStatelist = innerPickDeliveryUpCarRepository.findAllByDeptAndStateOther(deptId);
        otherStatelist.sort(Comparator.comparing(InnerPickDeliveryUpCar::getCreateDate).reversed());
        // 待内协接收
        List<InnerPickDeliveryUpCar> returnStatelist = innerPickDeliveryUpCarRepository.findAllByDeptAndStateReturn(deptId);
        returnStatelist.sort(Comparator.comparing(InnerPickDeliveryUpCar::getCreateDate).reversed());
        Map map = new HashMap();
        map.put("get", innerPickDeliveryUpCarListToMapList(getStatelist));
        map.put("other", innerPickDeliveryUpCarListToMapList(otherStatelist));
        map.put("return", innerPickDeliveryUpCarListToMapList(returnStatelist));
        return map;
    }

    /**
     * 将内协交接车单列表转成Map列表
     *
     * @param list
     * @return
     */
    public List innerPickDeliveryUpCarListToMapList(List<InnerPickDeliveryUpCar> list) {
        List<Map> mapList = new ArrayList<>();
        list.forEach(innerPickDeliveryUpCar -> {
            Map map = MapUtil.mapped(innerPickDeliveryUpCar);
            Dept belongDept = innerPickDeliveryUpCar.getBelongDept();
            Dept otherSideDept = innerPickDeliveryUpCar.getOtherSideDept();
            Map belongMap = findStoreAddress(belongDept);
            Map otherSideMap = findStoreAddress(otherSideDept);
            map.put("belongDept", belongMap);
            map.put("otherSideDept", otherSideMap);
            ArrayList arrayList = (ArrayList) map.get("innerPickDeliveryUpCarItemList");
            for (int i = 0; i < arrayList.size(); i++) {
                HashMap hashMap = (HashMap) arrayList.get(i);
                HashMap belongStr = (HashMap) hashMap.get("belongDept");
                HashMap otherSideStr = (HashMap) hashMap.get("otherSideDept");
                if (belongStr != null) {
                    Dept belongDept1 = deptRepository.findOne(String.valueOf(belongStr.get("id")));
                    Dept otherSideDept1 = deptRepository.findOne(String.valueOf(otherSideStr.get("id")));
                    Map belongMap1 = findStoreAddress(belongDept1);
                    Map otherSideMap1 = findStoreAddress(otherSideDept1);
                    hashMap.put("belongDept", belongMap1);
                    hashMap.put("otherSideDept", otherSideMap1);
                }
            }
            mapList.add(map);
        });
        return mapList;
    }


    /**
     * 在店车辆
     *
     * @param request
     * @return
     */
    public Map findCarByDept(SimpleRequest request) {
        String deptId = request.get("DeptId");
        Dept dept = deptRepository.findOne(deptId);
        Map map = new HashMap();
        List<Map> pickUpCarMapList = new ArrayList<>();
        List<Map> copyPickUpCarMapList = new ArrayList<>();
        List<Map> notRepealMapList = new ArrayList<>();
        List<Map> noticePickCarMapList = new ArrayList<>();
        List<String> notRepealLiceseNumberList = new ArrayList<>();
        // 到店车辆
        List<PickUpCar> pickUpCarList = pickUpCarRepository.findByDeptAndState(dept, "approve");
        pickUpCarList.sort(Comparator.comparing(PickUpCar::getCreateDate).reversed());
        pickUpCarList.forEach(pickUpCar -> {
            pickUpCarMapList.add(MapUtil.mapper("licenseNumber", pickUpCar.getLicenseNumber(),
                    "id", pickUpCar.getId(),
                    "innerBusinessType", pickUpCar.getInnerBusinessType(),
                    "phoneNumber", pickUpCar.getPhoneNumber(),
                    "customerName", pickUpCar.getCustomerName(),
                    "note", pickUpCar.getNote(),
                    "customerLevelName", pickUpCar.getFnCustomerExpand() == null ? null : pickUpCar.getFnCustomerExpand().getCustomerLevelName(),
                    "getCarName", pickUpCar.getCreator() == null ? null : partyRoleRepository.findOne(pickUpCar.getCreator()).getName(),
                    "pickUpCarDate", pickUpCar.getCreateDate()));
        });
        List<InnerPickDeliveryUpCar> innerPickDeliveryUpCarList = innerPickDeliveryUpCarRepository.findByOtherSideDeptAndState(dept, "get");
        innerPickDeliveryUpCarList.sort(Comparator.comparing(InnerPickDeliveryUpCar::getCreateDate).reversed());
        innerPickDeliveryUpCarList.stream().forEach(innerPickDeliveryUpCar -> {
            pickUpCarMapList.add(MapUtil.mapper("licenseNumber", innerPickDeliveryUpCar.getLicenseNumber(),
                    "id", innerPickDeliveryUpCar.getId(),
                    "innerBusinessType", innerPickDeliveryUpCar.getInnerBusinessType(),
                    "note", null,
                    "customerName", innerPickDeliveryUpCar.getCustomerName(),
                    "phoneNumber", innerPickDeliveryUpCar.getFnCustomerExpand() == null ? null : innerPickDeliveryUpCar.getFnCustomerExpand().getMobile(),
                    "customerLevelName", innerPickDeliveryUpCar.getFnCustomerExpand() == null ? null : innerPickDeliveryUpCar.getFnCustomerExpand().getCustomerLevelName(),
                    "pickUpCarDate", innerPickDeliveryUpCar.getCreateDate(),
                    "getCarName", getCarName(innerPickDeliveryUpCar),
                    "otherSideDept", innerPickDeliveryUpCar.getBelongDept())); // 发起内协门店

        });

        // 内协车辆
        List<InnerPickDeliveryUpCar> notRepealList = innerPickDeliveryUpCarRepository.findByBelongDept(deptId);
        notRepealList.sort(Comparator.comparing(InnerPickDeliveryUpCar::getCreateDate).reversed());
        notRepealList.forEach(innerPickDeliveryUpCar -> {
            notRepealMapList.add(MapUtil.mapper("licenseNumber", innerPickDeliveryUpCar.getLicenseNumber(),
                    "id", innerPickDeliveryUpCar.getId(),
                    "note", null,
                    "innerBusinessType", innerPickDeliveryUpCar.getInnerBusinessType(),
                    "phoneNumber", innerPickDeliveryUpCar.getFnCustomerExpand() == null ? null : innerPickDeliveryUpCar.getFnCustomerExpand().getMobile(),
                    "customerLevelName", innerPickDeliveryUpCar.getFnCustomerExpand() == null ? null : innerPickDeliveryUpCar.getFnCustomerExpand().getCustomerLevelName(),
                    "pickUpCarDate", innerPickDeliveryUpCar.getCreateDate(),
                    "customerName", innerPickDeliveryUpCar.getCustomerName(),
                    "getCarName", getCarName(innerPickDeliveryUpCar),
                    "otherSideDept", innerPickDeliveryUpCar.getOtherSideDept()));
            notRepealLiceseNumberList.add(innerPickDeliveryUpCar.getLicenseNumber());
        });


        // 等待交车
        List<PickUpCar> noticePickCarList = pickUpCarList.stream().filter(PickUpCar::isNoticePickCar).collect(Collectors.toList());
        noticePickCarList.sort(Comparator.comparing(PickUpCar::getCreateDate).reversed());
        noticePickCarList.forEach(pickUpCar -> {
            noticePickCarMapList.add(MapUtil.mapper("licenseNumber", pickUpCar.getLicenseNumber(),
                    "id", pickUpCar.getId(),
                    "innerBusinessType", pickUpCar.getInnerBusinessType(),
                    "phoneNumber", pickUpCar.getPhoneNumber(),
                    "note", pickUpCar.getNote(),
                    "customerName", pickUpCar.getCustomerName(),
                    "noticeDate", pickUpCar.getNoticeDate(),
                    "getCarName", pickUpCar.getCreator() == null ? null : partyRoleRepository.findOne(pickUpCar.getCreator()).getName(),
                    "customerLevelName", pickUpCar.getFnCustomerExpand() == null ? null : pickUpCar.getFnCustomerExpand().getCustomerLevelName(),
                    "pickUpCarDate", pickUpCar.getCreateDate()));
        });
        copyPickUpCarMapList = pickUpCarMapList.stream().filter(m -> !notRepealLiceseNumberList.contains(m.get("licenseNumber"))).collect(Collectors.toList());

        map.put("get", copyPickUpCarMapList);
        map.put("other", notRepealMapList);
        map.put("return", noticePickCarMapList);
        return map;
    }

    String getCarName(InnerPickDeliveryUpCar innerPickDeliveryUpCar){
        InnerPickDeliveryUpCarItem get = innerPickDeliveryUpCar.getInnerPickDeliveryUpCarItemList().stream()
                .filter(innerPickDeliveryUpCarItem -> innerPickDeliveryUpCarItem.getNodeDescription().equals("get"))
                .findFirst().orElseGet(() -> null);
        return get==null? null :get.getOperateUid()==null? null : get.getOperateUid().getName();
    }

    /**
     * 基地归还时同步到旧系统
     *
     * @param innerPickDeliveryUpCar
     */
    public void synGHJJCD(InnerPickDeliveryUpCar innerPickDeliveryUpCar, InnerPickDeliveryUpCarItem item) {

        JSONObject JJCD = new JSONObject();
        JJCD.put("JJCDH", innerPickDeliveryUpCar.getJJCDH());
        JJCD.put("LYDJLX", "NXJC0");
        switch (item.getFuelMeter().getDescription()) {
            case "空":
                JJCD.put("YBWDS", "E");
                break;
            case "1/4":
                JJCD.put("YBWDS", "1/4");
                break;
            case "2/4":
                JJCD.put("YBWDS", "1/2");
                break;
            case "3/4":
                JJCD.put("YBWDS", "3/4");
                break;
            case "满":
                JJCD.put("YBWDS", "F");
                break;

        }
        JJCD.put("GHMDID", innerPickDeliveryUpCar.getOtherSideDept().getId());
        JJCD.put("GHMDMC", innerPickDeliveryUpCar.getOtherSideDept().getName());
        JJCD.put("GHR", item.getChauffeur().getName());
        JJCD.put("GHRQ_SJ", innerPickDeliveryUpCar.getOtherSideDate());
        JJCD.put("GHLCBDS", item.getMileage());
        JSONObject category = piManager.synErp("jjcdService.updateAppNXJJCD", JJCD);
    }


    /***
     * 功能： 根据车牌查找有效接车单
     * @param request
     * @return
     * @throws RuntimeException
     */
    public List findByLicenseNumberAndDept(SimpleRequest request) throws Exception {
        String licenseNumber = request.get("licenseNumber");
        String deptId = request.get("storeId");
        Dept dept = deptRepository.findOne(deptId);
//        Store store = storeRepository.findByDept(dept);
//        if (store == null) throw new RuntimeException("未找到对应门店。");
        List<InnerPickDeliveryUpCar> list = innerPickDeliveryUpCarRepository.findAll(
                JpaDsl.toCriteriaByEq("licenseNumber", licenseNumber)
        );
        list = list.stream().filter(innerPickDeliveryUpCar -> innerPickDeliveryUpCar.getState().equals("get")
                || innerPickDeliveryUpCar.getState().equals("return") || innerPickDeliveryUpCar.getState().equals("create")
                && (innerPickDeliveryUpCar.getOtherSideDept() == dept || innerPickDeliveryUpCar.getBelongDept() == dept)
        ).collect(Collectors.toList());
        return innerPickDeliveryUpCarListToMapList(list);
    }

    @FuncAlias(name = "获取时间")
    public String getDateByOperate(String innerPickDeliveryUpCarId, String operate) {
        InnerPickDeliveryUpCar innerPickDeliveryUpCar = innerPickDeliveryUpCarRepository.findOne(innerPickDeliveryUpCarId);
        if (innerPickDeliveryUpCar != null) {
            if ("归还时间".equals(operate))
                return DateUtil.dateToStr(innerPickDeliveryUpCar.getOtherSideDate(), "yyyy-MM-dd HH:mm:ss");
            if ("创建时间".equals(operate))
                return DateUtil.dateToStr(innerPickDeliveryUpCar.getCreateDate(), "yyyy-MM-dd HH:mm:ss");
        }
        return "";
    }


    public void testStatue(SimpleRequest re) {
        innerPickDeliveryUpCarRepository.saveAndFlush(innerPickDeliveryUpCarRepository.findOne(re.getJO().getString("id")));
    }


    public List<InnerPickDeliveryUpCar> synInnerPickDeliveryUpCar(SimpleRequest request){
        JSONObject jsonObject = request.getJO();
        String id = jsonObject.getString("id");
        int maxNum = jsonObject.getInteger("maxNum");
        Date date = new Date(jsonObject.getLong("timestamp"));
        List<InnerPickDeliveryUpCar> all = innerPickDeliveryUpCarRepository.findByLastUpdatedStampAndId(date,id, PageRequest.of(0, maxNum));
        return all;
    }
    public void testInnerPickCreateFnCustomerExpand(){
//        AbstractPlan abstractPlan = SpringManager.getBean(AbstractPlan.class);
//        InnerPickDeliveryUpCar innerPickDeliveryUpCar = innerPickDeliveryUpCarRepository.findOne("000000039219");
//        abstractPlan.copyFnCustomerExpandToOrderSide(innerPickDeliveryUpCar.getFnCustomerExpand(),innerPickDeliveryUpCar.getOtherSideDept());
    }

    /**
     * 修改数据
     * @param request {"page":"0", "size":"30"}
     */
    public void dealCollectData(SimpleRequest request) {
        JSONObject jsonObject = request.getJO();
        int page = jsonObject.getInteger("page");
        int size = jsonObject.getInteger("size");

        Sort sort = new Sort(Sort.Direction.ASC, "createDate");
        while (true) {
            Pageable pageable = PageRequest.of(page, size, sort);
            int execute = 0;
            try {
                execute = execute(() -> {
                    Page<InnerPickDeliveryUpCar> maps = innerPickDeliveryUpCarRepository.findAll(pageable);
                    invoke("fn.innerPickDeliveryUpCar.dealCollectDataToMQ",maps);
                    return maps.getContent().size();
                });
            } catch (Exception e) {
                //即使异常也不处理，宁愿不汇扩展表也不要影响业务
            }
            page = page + 1;
            if (execute < size) {
                break;
            }
            System.out.println("============================== page: " + page);
        }
    }

    private void dealMapData(SimpleRequest request) {
        JSONObject jo = request.getJO();
        InnerPickDeliveryUpCar innerPickDeliveryUpCar = innerPickDeliveryUpCarRepository.findOne(jo.getString("ID"));
        AbstractPlan abstractPlan = SpringManager.getBean(AbstractPlan.class);
        abstractPlan.copyFnCustomerExpandToOrderSide(innerPickDeliveryUpCar.getFnCustomerExpand(),innerPickDeliveryUpCar.getOtherSideDept());
    }
    private List<Map> dealCollectDataToMQ(SimpleRequest request) {
        List<Map> all = innerPickDeliveryUpCarRepository.findAllByIdNotIn(Arrays.asList("1"));
        return all;
    }


    @Autowired
    private TransactionTemplate transactionTemplate;

    public int execute(RetailOrderExtensionService.Callback callback) {
        return transactionTemplate.execute(status -> {
            try {
                return callback.execute();
            } catch (Exception e) {
                e.printStackTrace();
                status.isRollbackOnly();
                throw e;
            }
        });
    }
}
